package com.mlethe.library.recyclerview.adapter;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.content.Context;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.widget.FrameLayout;

import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.ListUpdateCallback;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import com.mlethe.library.recyclerview.AdapterLoadSir;
import com.mlethe.library.recyclerview.animation.AlphaInAnimation;
import com.mlethe.library.recyclerview.animation.BaseAnimation;
import com.mlethe.library.recyclerview.animation.ScaleInAnimation;
import com.mlethe.library.recyclerview.animation.SlideInBottomAnimation;
import com.mlethe.library.recyclerview.animation.SlideInLeftAnimation;
import com.mlethe.library.recyclerview.animation.SlideInRightAnimation;
import com.mlethe.library.recyclerview.callback.AbstractLoadCallback;
import com.mlethe.library.recyclerview.callback.Callback;
import com.mlethe.library.recyclerview.diff.BaseDiffCallback;
import com.mlethe.library.recyclerview.diff.AdapterListUpdateCallback;
import com.mlethe.library.recyclerview.listener.MultiTypeSupport;
import com.mlethe.library.recyclerview.listener.OnConvertListener;
import com.mlethe.library.recyclerview.listener.OnItemClickListener;
import com.mlethe.library.recyclerview.listener.OnItemLongClickListener;
import com.mlethe.library.recyclerview.listener.OnLoadListener;
import com.mlethe.library.recyclerview.viewholder.SimpleViewHolder;
import com.mlethe.library.recyclerview.viewholder.ViewHolder;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static android.view.ViewGroup.LayoutParams;

/**
 * 添加头部 、添加底部、设置Callback
 * Created by Mlethe on 2018/12/28.
 */
public abstract class UniversalAdapter<T, VH extends ViewHolder> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private Context mContext;
    private LayoutInflater mInflater;
    /**
     * 数据
     */
    private List<T> mData;
    /**
     * 布局
     */
    private int mLayoutId;
    /**
     * 多布局支持
     */
    private MultiTypeSupport<T> mMultiTypeSupport;
    /**
     * View绑定数据
     */
    private OnConvertListener<T> mOnConvertListener;
    /**
     * item的点击事件
     */
    private OnItemClickListener<T> mItemClickListener;
    /**
     * item的长按事件
     */
    private OnItemLongClickListener<T> mLongClickListener;

    private static final int BASE_ITEM_TYPE_HEADER = Integer.MAX_VALUE - 20000;
    private static final int BASE_ITEM_TYPE_FOOTER = Integer.MAX_VALUE - 10000;
    public static final int EMPTY_VIEW = Integer.MAX_VALUE;
    public static final int LOADING_VIEW = Integer.MAX_VALUE - 1;

    private FrameLayout mEmptyLayout;
    private int mEmptyWidth = LayoutParams.MATCH_PARENT, mEmptyHeight = LayoutParams.MATCH_PARENT;
    private boolean mIsUseEmpty = false;
    private boolean isEmpty = false;
    private Callback mCallback;
    private View.OnClickListener mOnClickListener;
    private Object mBindData;

    private SparseArray<View> mHeaderViews;
    private SparseArray<View> mFooterViews;
    private boolean mHeadAndEmptyEnable;
    private boolean mFootAndEmptyEnable;

    /**
     * 默认
     */
    private static final int STATE_DEFAULT = 10000;
    /**
     * 加载中
     */
    private static final int STATE_LOADING = 10001;
    /**
     * 加载完成
     */
    private static final int STATE_END = 10002;
    /**
     * 加载失败
     */
    private static final int STATE_FAIL = 10003;
    private int mLoadState = STATE_DEFAULT;
    private boolean mEnableLoadMore = false;
    /**
     * 数据是否全部加载完成，如果完成就不能在触发加载事件
     */
    private boolean mFooterNoMoreData = false;
    /**
     * 底部是否显示数据全部加载完成
     */
    private boolean mFooterNoMoreDataShow = true;
    private AbstractLoadCallback mLoadCallback;
    private OnLoadListener mOnLoadListener;
    /**
     * 控制多出多少条的时候调用 onLoadMore
     */
    private int limitNumberToCallLoadMore = 1;

    private int mSpanCount = -1;

    private boolean mFirstOnlyEnable = true;
    private boolean mOpenAnimationEnable = false;
    private Interpolator mInterpolator = new LinearInterpolator();
    private int mDuration = 300;
    private int mLastPosition = -1;

    private BaseAnimation mCustomAnimation;
    private BaseAnimation mSelectAnimation = new AlphaInAnimation();

    //Animation
    /**
     * Use with {@link #openLoadAnimation}
     */
    public static final int ALPHAIN = 0x00000001;
    /**
     * Use with {@link #openLoadAnimation}
     */
    public static final int SCALEIN = 0x00000002;
    /**
     * Use with {@link #openLoadAnimation}
     */
    public static final int SLIDEIN_BOTTOM = 0x00000003;
    /**
     * Use with {@link #openLoadAnimation}
     */
    public static final int SLIDEIN_LEFT = 0x00000004;
    /**
     * Use with {@link #openLoadAnimation}
     */
    public static final int SLIDEIN_RIGHT = 0x00000005;

    /**
     * 方向 {@link RecyclerView#VERTICAL} {@link RecyclerView#HORIZONTAL}
     */
    private int mOrientation = RecyclerView.VERTICAL;

    @IntDef({ALPHAIN, SCALEIN, SLIDEIN_BOTTOM, SLIDEIN_LEFT, SLIDEIN_RIGHT})
    @Retention(RetentionPolicy.SOURCE)
    public @interface AnimationType {
    }

    public UniversalAdapter(int layoutId) {
        this(new ArrayList<T>(), layoutId);
    }

    public UniversalAdapter(MultiTypeSupport<T> multiTypeSupport) {
        this(new ArrayList<T>(), multiTypeSupport);
    }

    public UniversalAdapter(List<T> data, int layoutId) {
        this.mData = data;
        this.mLayoutId = layoutId;
    }

    public UniversalAdapter(List<T> data, MultiTypeSupport<T> multiTypeSupport) {
        this(data, -1);
        this.mMultiTypeSupport = multiTypeSupport;
    }

    /**
     * 根据当前位置获取不同的viewType
     */
    @Override
    public int getItemViewType(int position) {
        if (isEmptyLayout(position)) {
            return EMPTY_VIEW;
        } else if (isHeaderView(position)) {
            return mHeaderViews.keyAt(position);
        } else if (isFooterView(position)) {
            int size = 1;
            if (!isEmpty) {
                size = getDataSize();
            }
            return mFooterViews.keyAt(position - getHeaderCount() - size);
        } else if (isLoadView(position)) {
            return LOADING_VIEW;
        }
        int realPos = position - getHeaderCount();
        if (mMultiTypeSupport != null) {
            return mMultiTypeSupport.getLayoutId(getItem(realPos), realPos);
        }
        return super.getItemViewType(realPos);
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == EMPTY_VIEW) {
            if (mEmptyLayout != null) {
                ViewParent viewParent = mEmptyLayout.getParent();
                if (viewParent instanceof ViewGroup) {
                    ((ViewGroup) viewParent).removeView(mEmptyLayout);
                }
            }
            return createSimpleViewHolder(createEmptyLayout(parent));
        } else if (viewType == LOADING_VIEW) {
            return createSimpleViewHolder(createLoadView(parent));
        } else if (isHeaderViewType(viewType)) {
            View header = mHeaderViews.get(viewType);
            ViewParent viewParent = header.getParent();
            if (viewParent instanceof ViewGroup) {
                ((ViewGroup) viewParent).removeView(header);
            }
            return createSimpleViewHolder(header);
        } else if (isFooterViewType(viewType)) {
            View footer = mFooterViews.get(viewType);
            ViewParent viewParent = footer.getParent();
            if (viewParent instanceof ViewGroup) {
                ((ViewGroup) viewParent).removeView(footer);
            }
            return createSimpleViewHolder(footer);
        } else if (mMultiTypeSupport != null) {
            View itemView = mInflater.inflate(viewType, parent, false);
            return createViewHolder(itemView);
        }
        View itemView = mInflater.inflate(mLayoutId, parent, false);
        return createViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
        int itemViewType = holder.getItemViewType();
        if (itemViewType == EMPTY_VIEW || itemViewType == LOADING_VIEW || isHeaderViewType(itemViewType) || isFooterViewType(itemViewType)) {
            return;
        }
        if (!(holder instanceof ViewHolder)) {
            return;
        }
        if (mItemClickListener != null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mItemClickListener == null) {
                        return;
                    }
                    int position = holder.getAdapterPosition();
                    if (position == RecyclerView.NO_POSITION) {
                        return;
                    }
                    int realPos = position - getHeaderCount();
                    T item = getItem(realPos);
                    mItemClickListener.onItemClick(v, item, realPos);
                }
            });
        }
        if (mLongClickListener != null) {
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    if (mLongClickListener == null) {
                        return false;
                    }
                    int position = holder.getAdapterPosition();
                    if (position == RecyclerView.NO_POSITION) {
                        return false;
                    }
                    int realPos = position - getHeaderCount();
                    T item = getItem(realPos);
                    return mLongClickListener.onLongClick(v, item, realPos);
                }
            });
        }
        int realPos = position - getHeaderCount();
        T item = getItem(realPos);
        if (mOnConvertListener != null) {
            mOnConvertListener.convert((VH) holder, item, realPos);
        }
        convert((VH) holder, item, realPos);
    }

    @Override
    public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position, @NonNull List<Object> payloads) {
        if (payloads.isEmpty()) {
            onBindViewHolder(holder, position);
            return;
        }
        int itemViewType = holder.getItemViewType();
        if (itemViewType == EMPTY_VIEW || itemViewType == LOADING_VIEW || isHeaderViewType(itemViewType) || isFooterViewType(itemViewType)) {
            return;
        }
        if (!(holder instanceof ViewHolder)) {
            return;
        }
        if (mItemClickListener != null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mItemClickListener == null) {
                        return;
                    }
                    int position = holder.getAdapterPosition();
                    if (position == RecyclerView.NO_POSITION) {
                        return;
                    }
                    int realPos = position - getHeaderCount();
                    T item = getItem(realPos);
                    mItemClickListener.onItemClick(v, item, realPos);
                }
            });
        }
        if (mLongClickListener != null) {
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    if (mLongClickListener == null) {
                        return false;
                    }
                    int position = holder.getAdapterPosition();
                    if (position == RecyclerView.NO_POSITION) {
                        return false;
                    }
                    int realPos = position - getHeaderCount();
                    T item = getItem(realPos);
                    return mLongClickListener.onLongClick(v, item, realPos);
                }
            });
        }
        int realPos = position - getHeaderCount();
        T item = getItem(realPos);
        if (mOnConvertListener != null) {
            mOnConvertListener.convert((VH) holder, item, realPos, payloads);
        }
        convert((VH) holder, item, realPos, payloads);
    }

    @Override
    public int getItemCount() {
        int count;
        if (getEmptyViewCount() == 1) {
            isEmpty = true;
            count = 1;
            if (mHeadAndEmptyEnable) {
                count += getHeaderCount();
            }
            if (mFootAndEmptyEnable) {
                count += getFooterCount();
            }
        } else {
            isEmpty = false;
            count = getHeaderCount() + getDataSize() + getFooterCount();
            if (getLoadViewCount() == 1) {
                if (mFooterNoMoreData && !mFooterNoMoreDataShow) {
                    return count;
                }
                count++;
            }
        }
        return count;
    }

    @Override
    public void onAttachedToRecyclerView(final RecyclerView recyclerView) {
        mContext = recyclerView.getContext();
        mInflater = LayoutInflater.from(mContext);
        recyclerView.addOnScrollListener(mOnScrollListener);
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
            mOrientation = gridLayoutManager.getOrientation();
            final GridLayoutManager.SpanSizeLookup spanSizeLookup = gridLayoutManager.getSpanSizeLookup();
            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    int spanCount = gridLayoutManager.getSpanCount();
                    mSpanCount = spanCount;
                    if (isEmptyLayout(position) || isHeaderView(position) || isFooterView(position) || isLoadView(position)) {
                        return spanCount;
                    } else if (spanSizeLookup != null) {
                        return spanSizeLookup.getSpanSize(position - getHeaderCount());
                    }
                    return 1;
                }
            });
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
            mOrientation = staggeredGridLayoutManager.getOrientation();
            mSpanCount = staggeredGridLayoutManager.getSpanCount();
        } else if (layoutManager instanceof LinearLayoutManager) {
            LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
            mOrientation = linearLayoutManager.getOrientation();
            mSpanCount = 0;
        }
    }

    @Override
    public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
        int itemViewType = holder.getItemViewType();
        if (itemViewType == EMPTY_VIEW || itemViewType == LOADING_VIEW || isHeaderViewType(itemViewType) || isFooterViewType(itemViewType)) {
            otherViewAttachedToWindow(holder);
        } else {
            addAnimation(holder);
        }
    }

    /**
     * 显示时添加动画
     *
     * @param holder
     */
    private void addAnimation(RecyclerView.ViewHolder holder) {
        if (mOpenAnimationEnable) {
            if (!mFirstOnlyEnable || holder.getLayoutPosition() > mLastPosition) {
                BaseAnimation animation;
                if (mCustomAnimation != null) {
                    animation = mCustomAnimation;
                } else {
                    animation = mSelectAnimation;
                }
                startAnim(animation.getAnimators(holder.itemView));
                mLastPosition = holder.getLayoutPosition();
            }
        }
    }

    /**
     * 开始加载动画
     *
     * @param animators 动画数组
     */
    protected void startAnim(Animator[] animators) {
        if (animators != null && animators.length > 0) {
            AnimatorSet animatorSet = new AnimatorSet();
            animatorSet.playTogether(animators);
            animatorSet.setInterpolator(mInterpolator);
            animatorSet.setDuration(mDuration).start();
        }
    }

    /**
     * 瀑布流布局设置头部、底部
     *
     * @param holder
     */
    private void otherViewAttachedToWindow(RecyclerView.ViewHolder holder) {
        LayoutParams lp = holder.itemView.getLayoutParams();
        if (lp instanceof StaggeredGridLayoutManager.LayoutParams) {
            StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
            p.setFullSpan(true);
        }
    }

    private RecyclerView.OnScrollListener mOnScrollListener = new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
            // 最后一个可见的Item的position
            int lastVisibleItemPosition = -1;
            if (layoutManager instanceof GridLayoutManager) {
                lastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
            } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                int[] into = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
                ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(into);
                lastVisibleItemPosition = findMax(into);
            } else if (layoutManager instanceof LinearLayoutManager) {
                lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
            }
            if (lastVisibleItemPosition != -1) {
                int adjAdapterItemCount = layoutManager.getItemCount();
                int childCount = layoutManager.getChildCount();
                if (
                        childCount > 0
                                && lastVisibleItemPosition >= adjAdapterItemCount - limitNumberToCallLoadMore
                                && adjAdapterItemCount >= childCount
                                && !mFooterNoMoreData
                                && (mLoadState == STATE_DEFAULT || mLoadState == STATE_END)
                                && !isEmpty
                ) {
                    mLoadState = STATE_LOADING;
                    if (mLoadCallback != null) {
                        mLoadCallback.onLoading();
                    }
                    if (mOnLoadListener != null) {
                        mOnLoadListener.onLoad();
                    }
                }
            }
        }
    };

    @Override
    public void unregisterAdapterDataObserver(@NonNull RecyclerView.AdapterDataObserver observer) {
        super.unregisterAdapterDataObserver(observer);
        release();
    }

    /**
     * 设置上下文
     *
     * @param context
     * @return
     */
    public UniversalAdapter<T, VH> setContext(Context context) {
        this.mContext = context;
        this.mInflater = LayoutInflater.from(mContext);
        return this;
    }

    /**
     * 获取上下文
     *
     * @return
     */
    public Context getContext() {
        return mContext;
    }

    /**
     * 获取方向
     *
     * @return 方向 {@link RecyclerView#VERTICAL} {@link RecyclerView#HORIZONTAL}
     */
    public int getOrientation() {
        return mOrientation;
    }

    /**
     * 获取 position
     *
     * @param viewHolder
     * @return
     */
    protected int getViewHolderPosition(RecyclerView.ViewHolder viewHolder) {
        int adapterPosition = viewHolder.getAdapterPosition();
        if (adapterPosition < 0) {
            return adapterPosition;
        }
        return adapterPosition - getHeaderCount();
    }

    /**
     * 判断position是不是data的范围
     *
     * @param position
     * @return
     */
    protected boolean inRange(int position) {
        return position >= 0 && position < getDataSize();
    }

    /**
     * 实现数据绑定
     *
     * @param holder
     * @param item
     * @param position
     */
    protected abstract void convert(@NonNull VH holder, T item, int position);

    /**
     * 实现数据绑定
     *
     * @param holder
     * @param item
     * @param position
     * @param payloads
     */
    protected void convert(@NonNull VH holder, T item, int position, @NonNull List<Object> payloads) {
    }

    /**
     * 获取简单的 RecyclerView.ViewHolder
     *
     * @return
     */
    private RecyclerView.ViewHolder createSimpleViewHolder(View view) {
        return new SimpleViewHolder(view);
    }

    /**
     * if you want to use subclass of BaseViewHolder in the adapter,
     * you must override the method to create new ViewHolder.
     *
     * @param view view
     * @return new ViewHolder
     */
    @SuppressWarnings("unchecked")
    protected VH createViewHolder(@NonNull View view) {
        Class<?> temp = getClass();
        Class<?> z = null;
        while (z == null && null != temp) {
            z = getInstancedGenericKClass(temp);
            temp = temp.getSuperclass();
        }
        VH vh;
        // 泛型擦除会导致z为null
        if (z == null) {
            vh = (VH) new ViewHolder(view);
        } else {
            vh = createGenericKInstance(z, view);
        }
        return vh != null ? vh : (VH) new ViewHolder(view);
    }

    /**
     * try to create Generic VH instance
     *
     * @param z
     * @param view
     * @return
     */
    @SuppressWarnings("unchecked")
    private VH createGenericKInstance(Class<?> z, View view) {
        try {
            Constructor<?> constructor;
            // inner and unstatic class
            if (z.isMemberClass() && !Modifier.isStatic(z.getModifiers())) {
                constructor = z.getDeclaredConstructor(getClass(), View.class);
                constructor.setAccessible(true);
                return (VH) constructor.newInstance(this, view);
            } else {
                constructor = z.getDeclaredConstructor(View.class);
                constructor.setAccessible(true);
                return (VH) constructor.newInstance(view);
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * get generic parameter K
     *
     * @param z
     * @return
     */
    private Class<?> getInstancedGenericKClass(Class<?> z) {
        Type type = z.getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            Type[] types = ((ParameterizedType) type).getActualTypeArguments();
            for (Type temp : types) {
                if (temp instanceof Class<?>) {
                    Class<?> tempClass = (Class<?>) temp;
                    if (ViewHolder.class.isAssignableFrom(tempClass)) {
                        return tempClass;
                    }
                } else if (temp instanceof ParameterizedType) {
                    Type rawType = ((ParameterizedType) temp).getRawType();
                    if (rawType instanceof Class && ViewHolder.class.isAssignableFrom((Class<?>) rawType)) {
                        return (Class<?>) rawType;
                    }
                }
            }
        }
        return null;
    }

    /**
     * 释放资源
     */
    public void release() {
        mContext = null;
        mInflater = null;
        if (mData != null) {
            mData.clear();
        }
        mLayoutId = -1;
        mMultiTypeSupport = null;
        mOnConvertListener = null;
        mItemClickListener = null;
        mLongClickListener = null;
        if (mHeaderViews != null) {
            mHeaderViews.clear();
            mHeaderViews = null;
        }
        if (mFooterViews != null) {
            mFooterViews.clear();
            mFooterViews = null;
        }
        releaseCallback();
        mCallback = null;
        mEmptyLayout = null;
        mOnClickListener = null;
        releaseLoadCallback();
        mLoadCallback = null;
        mOnLoadListener = null;
    }

    private void releaseCallback() {
        if (mCallback != null) {
            mCallback.onDestroy();
        }
    }

    private void releaseLoadCallback() {
        if (mLoadCallback != null) {
            mLoadCallback.onDestroy();
        }
    }

    private int findMax(int[] lastPositions) {
        int max = lastPositions[0];
        for (int value : lastPositions) {
            if (value > max) {
                max = value;
            }
        }
        return max;
    }

    /**
     * 创建空布局
     *
     * @param parent
     * @return
     */
    private View createEmptyLayout(@NonNull ViewGroup parent) {
        if (mEmptyLayout == null) {
            mEmptyLayout = new FrameLayout(parent.getContext());
            LayoutParams layoutParams = new LayoutParams(mEmptyWidth, mEmptyHeight);
            mEmptyLayout.setLayoutParams(layoutParams);
        }
        releaseCallback();
        if (mCallback == null) {
            Class<? extends Callback> defaultCallback = AdapterLoadSir.getDefault().getBuilder().getDefaultCallback();
            if (defaultCallback == null) {
                return mEmptyLayout;
            }
            mCallback = AdapterLoadSir.getDefault().getBuilder().getCallbacks().get(defaultCallback);
            if (mCallback == null) {
                throw new IllegalArgumentException(String.format("The Callback (%s) is nonexistent.", defaultCallback.getSimpleName()));
            }
        }
        final View view = mInflater.inflate(mCallback.getLayoutId(), mEmptyLayout, false);
        mCallback.onViewCreated(view);
        mCallback.bindClickListener(mOnClickListener);
        mCallback.bindData(mBindData);
        mEmptyLayout.addView(view);
        return mEmptyLayout;
    }

    /**
     * 创建加载布局
     *
     * @return
     */
    private View createLoadView(@NonNull ViewGroup parent) {
        releaseLoadCallback();
        if (mLoadCallback == null) {
            Class<? extends AbstractLoadCallback> callback = AdapterLoadSir.getDefault().getBuilder().getDefaultLoadCallback();
            if (callback == null) {
                throw new IllegalArgumentException("The defaultLoadCallback is not init.");
            }
            mLoadCallback = AdapterLoadSir.getDefault().getBuilder().getLoadCallbacks().get(callback);
            if (mLoadCallback == null) {
                throw new IllegalArgumentException(String.format("The LoadCallback (%s) is nonexistent.", callback.getSimpleName()));
            }
        }
        View view = mInflater.inflate(mLoadCallback.getLayoutId(), parent, false);
        mLoadCallback.onViewCreated(view);
        mLoadCallback.bindClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mLoadState != STATE_FAIL) {
                    return;
                }
                mLoadState = STATE_LOADING;
                if (mLoadCallback != null) {
                    mLoadCallback.onLoading();
                }
                if (mOnLoadListener != null) {
                    mOnLoadListener.onReload();
                }
            }
        });
        mLoadState = STATE_LOADING;
        if (mLoadCallback != null) {
            mLoadCallback.onLoading();
        }
        if (mOnLoadListener != null) {
            mOnLoadListener.onLoad();
        }
        return view;
    }

    /**
     * 设置动画类型
     *
     * @param animationType One of {@link #ALPHAIN}, {@link #SCALEIN}, {@link #SLIDEIN_BOTTOM},
     *                      {@link #SLIDEIN_LEFT}, {@link #SLIDEIN_RIGHT}.
     */
    public void openLoadAnimation(@AnimationType int animationType) {
        this.mOpenAnimationEnable = true;
        mCustomAnimation = null;
        switch (animationType) {
            case ALPHAIN:
                mSelectAnimation = new AlphaInAnimation();
                break;
            case SCALEIN:
                mSelectAnimation = new ScaleInAnimation();
                break;
            case SLIDEIN_BOTTOM:
                mSelectAnimation = new SlideInBottomAnimation();
                break;
            case SLIDEIN_LEFT:
                mSelectAnimation = new SlideInLeftAnimation();
                break;
            case SLIDEIN_RIGHT:
                mSelectAnimation = new SlideInRightAnimation();
                break;
            default:
                break;
        }
    }

    /**
     * 设置自定义动画
     *
     * @param animation ObjectAnimator
     */
    public UniversalAdapter<T, VH> openLoadAnimation(BaseAnimation animation) {
        this.mOpenAnimationEnable = true;
        this.mCustomAnimation = animation;
        return this;
    }

    /**
     * 开启item显示动画
     */
    public UniversalAdapter<T, VH> openLoadAnimation() {
        this.mOpenAnimationEnable = true;
        return this;
    }

    /**
     * 关闭item显示动画
     */
    public UniversalAdapter<T, VH> closeLoadAnimation() {
        this.mOpenAnimationEnable = false;
        return this;
    }

    /**
     * 设置动画执行时长
     *
     * @param duration 动画执行时长（毫秒）
     */
    public UniversalAdapter<T, VH> setDuration(int duration) {
        mDuration = duration;
        return this;
    }

    /**
     * 设置动画差值器
     *
     * @param interpolator 动画差值器
     */
    public UniversalAdapter<T, VH> setInterpolator(Interpolator interpolator) {
        mInterpolator = interpolator;
        return this;
    }

    /**
     * {@link #addAnimation(RecyclerView.ViewHolder)}
     *
     * @param firstOnly true 第一次加载时显示动画
     */
    public UniversalAdapter<T, VH> isFirstOnly(boolean firstOnly) {
        this.mFirstOnlyEnable = firstOnly;
        return this;
    }

    /**
     * 设置绑定事件
     *
     * @param onConvertListener
     */
    public UniversalAdapter<T, VH> setOnConvertListener(OnConvertListener<T> onConvertListener) {
        this.mOnConvertListener = onConvertListener;
        return this;
    }

    /**
     * 设置点击事件
     *
     * @param onItemClickListener
     * @return
     */
    public UniversalAdapter<T, VH> setOnItemClickListener(OnItemClickListener<T> onItemClickListener) {
        this.mItemClickListener = onItemClickListener;
        return this;
    }

    /**
     * 设置长按事件
     *
     * @param onItemLongClickListener
     * @return
     */
    public UniversalAdapter<T, VH> setOnItemLongClickListener(OnItemLongClickListener<T> onItemLongClickListener) {
        this.mLongClickListener = onItemLongClickListener;
        return this;
    }

    /**
     * 设置控制显示加载更多的条数
     *
     * @param limitNumberToCallLoadMore
     */
    public UniversalAdapter<T, VH> setLimitNumberToCallLoadMore(int limitNumberToCallLoadMore) {
        this.limitNumberToCallLoadMore = limitNumberToCallLoadMore;
        return this;
    }

    /**
     * 设置加载更多监听
     *
     * @param onLoadListener
     * @return
     */
    public UniversalAdapter<T, VH> setOnLoadListener(OnLoadListener onLoadListener) {
        this.mOnLoadListener = onLoadListener;
        return this;
    }

    /**
     * 数据加载完成时没有数据的View是否显示
     *
     * @param isShow
     */
    public void setNoDataShow(boolean isShow) {
        this.mFooterNoMoreDataShow = isShow;
    }

    /**
     * 设置是否还有数据
     *
     * @param noData
     */
    public void setNoData(boolean noData) {
        this.mFooterNoMoreData = noData;
    }

    /**
     * 加载失败
     */
    public void loadFail() {
        mLoadState = STATE_FAIL;
        if (mLoadCallback != null) {
            mLoadCallback.onLoadFail();
        }
    }

    /**
     * 加载完成
     */
    public void loadFinish() {
        mLoadState = STATE_END;
        if (mFooterNoMoreData) {
            if (mLoadCallback != null) {
                mLoadCallback.onNoData();
            }
        } else {
            if (mLoadCallback != null) {
                mLoadCallback.onLoaded();
            }
        }
    }

    /**
     * 加载完成
     *
     * @param list
     */
    public void loadFinish(List<T> list) {
        loadFinish(list, false);
    }

    /**
     * 加载完成
     *
     * @param list
     * @param isRefresh 是否刷新未添加数据时最后一行的数据，主要是使用ItemDecoration时使用。
     */
    public void loadFinish(List<T> list, boolean isRefresh) {
        mLoadState = STATE_END;
        int headerCount = getHeaderCount();
        int dataSize = getDataSize();
        if (mFooterNoMoreData) {
            if (mLoadCallback != null) {
                mLoadCallback.onNoData();
            }
            if (mData == null || list == null) {
                return;
            }
            int size = list.size();
            if (size <= 0) {
                return;
            }
            mData.addAll(list);
            notifyItemRangeInserted(headerCount + dataSize, size);
            if (!mFooterNoMoreDataShow) {
                notifyItemRemoved(headerCount + getDataSize() + getFooterCount() + size);
            }
        } else {
            if (mLoadCallback != null) {
                mLoadCallback.onLoaded();
            }
            if (mData == null || list == null) {
                return;
            }
            int size = list.size();
            if (size <= 0) {
                return;
            }
            mData.addAll(list);
            notifyItemRangeInserted(headerCount + dataSize, size);
        }
        if (isRefresh) {
            notifyLastRowChanged(dataSize);
        }
    }

    /**
     * 刷新最后一行(主要是使用ItemDecoration时使用)
     *
     * @param dataSize 添加数据前的数量
     */
    public void notifyLastRowChanged(int dataSize) {
        if (dataSize <= 0) {
            return;
        }
        if (mSpanCount > 0) {
            int startPosition = lastRowStartPosition(dataSize);
            if (startPosition >= 0) {
                int count = dataSize - startPosition;
                notifyItemRangeChanged(getHeaderCount() + startPosition, count);
            }
        } else if (mSpanCount == 0) {
            notifyItemChanged(getHeaderCount() + dataSize - 1);
        }
    }

    /**
     * 最后一行开始的position
     *
     * @return
     */
    private int lastRowStartPosition(int itemCount) {
        if (mSpanCount <= 0) {
            return -1;
        }
        if (itemCount % mSpanCount == 0) {
            return (itemCount / mSpanCount - 1) * mSpanCount;
        }
        return itemCount / mSpanCount * mSpanCount;
    }

    /**
     * 设置加载更多
     *
     * @param callback
     * @return
     */
    public UniversalAdapter<T, VH> setLoadCallback(Class<? extends AbstractLoadCallback> callback) {
        releaseLoadCallback();
        mLoadCallback = AdapterLoadSir.getDefault().getBuilder().getLoadCallbacks().get(callback);
        if (mLoadCallback == null) {
            throw new IllegalArgumentException(String.format("The LoadCallback (%s) is nonexistent.", callback.getSimpleName()));
        }
        return this;
    }

    /**
     * 设置是否启用上拉加载更多（默认不启用）
     *
     * @param enabled 是否启用
     * @return UniversalAdapter
     */
    public UniversalAdapter<T, VH> setEnableLoadMore(boolean enabled) {
        this.mEnableLoadMore = enabled;
        return this;
    }

    /**
     * 设置默认页面的数据
     *
     * @param data
     * @return
     */
    public UniversalAdapter<T, VH> setDefaultBindData(Object data) {
        this.mBindData = data;
        return this;
    }


    /**
     * 设置默认页面的点击事件
     *
     * @param onClickListener
     * @return
     */
    public UniversalAdapter<T, VH> setDefaultOnClickListener(View.OnClickListener onClickListener) {
        this.mOnClickListener = onClickListener;
        return this;
    }

    /**
     * 显示默认Callback
     */
    public void showDefaultCallback() {
        showDefaultCallback(false);
    }

    /**
     * 显示默认Callback
     *
     * @param isReplace 相同callback 显示 是否替换显示, true 替换, false 不替换
     */
    public void showDefaultCallback(boolean isReplace) {
        showDefaultCallback(null, isReplace, null);
    }

    /**
     * 显示默认Callback
     *
     * @param data 绑定的数据
     */
    public void showDefaultCallback(Object data) {
        showDefaultCallback(data, false, null);
    }

    /**
     * 显示默认Callback
     *
     * @param onClickListener
     */
    public void showDefaultCallback(View.OnClickListener onClickListener) {
        showDefaultCallback(null, false, onClickListener);
    }

    /**
     * 显示默认Callback
     *
     * @param data            绑定的数据
     * @param onClickListener
     */
    public void showDefaultCallback(Object data, View.OnClickListener onClickListener) {
        showDefaultCallback(data, false, onClickListener);
    }

    /**
     * 显示默认Callback
     *
     * @param isReplace       相同callback 显示 是否替换显示, true 替换, false 不替换
     * @param onClickListener
     */
    public void showDefaultCallback(boolean isReplace, View.OnClickListener onClickListener) {
        showDefaultCallback(null, isReplace, onClickListener);
    }

    /**
     * 显示默认Callback
     *
     * @param data            绑定的数据
     * @param isReplace       相同callback 显示 是否替换显示, true 替换, false 不替换
     * @param onClickListener
     */
    public void showDefaultCallback(Object data, boolean isReplace, View.OnClickListener onClickListener) {
        showCallback(AdapterLoadSir.getDefault().getBuilder().getDefaultCallback(), data, isReplace, onClickListener);
    }

    /**
     * 显示Callback
     *
     * @param callback
     */
    public void showCallback(Class<? extends Callback> callback) {
        showCallback(callback, null, false, null);
    }

    /**
     * 显示Callback
     *
     * @param callback
     * @param data     绑定的数据
     */
    public void showCallback(Class<? extends Callback> callback, Object data) {
        showCallback(callback, data, false, null);
    }

    /**
     * 显示Callback
     *
     * @param callback
     * @param data      绑定的数据
     * @param isReplace 相同callback 显示 是否替换显示, true 替换, false 不替换
     */
    public void showCallback(Class<? extends Callback> callback, Object data, boolean isReplace) {
        showCallback(callback, data, isReplace, null);
    }

    /**
     * 显示Callback
     *
     * @param callback
     * @param isReplace 相同callback 显示 是否替换显示, true 替换, false 不替换
     */
    public void showCallback(Class<? extends Callback> callback, boolean isReplace) {
        showCallback(callback, null, isReplace, null);
    }

    /**
     * 显示Callback
     *
     * @param callback
     * @param onClickListener
     */
    public void showCallback(Class<? extends Callback> callback, View.OnClickListener onClickListener) {
        showCallback(callback, null, false, onClickListener);
    }

    /**
     * 显示Callback
     *
     * @param callback
     * @param data            绑定的数据
     * @param onClickListener
     */
    public void showCallback(Class<? extends Callback> callback, Object data, View.OnClickListener onClickListener) {
        showCallback(callback, data, false, onClickListener);
    }

    /**
     * 显示Callback
     *
     * @param callback
     * @param data            绑定的数据
     * @param isReplace       相同callback 显示 是否替换显示, true 替换, false 不替换
     * @param onClickListener 点击事件监听
     */
    public final void showCallback(Class<? extends Callback> callback, Object data, boolean isReplace, final View.OnClickListener onClickListener) {
        mBindData = data;
        mOnClickListener = onClickListener;
        if (mCallback != null) {
            if (mCallback.getClass().equals(callback) && !isReplace) {
                mCallback.bindClickListener(mOnClickListener);
                mCallback.bindData(mBindData);
                return;
            }
        }
        releaseCallback();
        mCallback = AdapterLoadSir.getDefault().getBuilder().getCallbacks().get(callback);
        if (mCallback == null) {
            throw new IllegalArgumentException(String.format("The Callback (%s) is nonexistent.", callback.getSimpleName()));
        }
        if (mEmptyLayout != null) {
            mEmptyLayout.removeAllViews();
            final View view = mInflater.inflate(mCallback.getLayoutId(), mEmptyLayout, false);
            mCallback.onViewCreated(view);
            mCallback.bindClickListener(mOnClickListener);
            mCallback.bindData(mBindData);
            mEmptyLayout.addView(view);
        }
    }

    /**
     * 设置空布局的宽度和高度
     *
     * @param width
     * @param height
     * @return
     */
    public UniversalAdapter<T, VH> setEmptyWidthAndHeight(int width, int height) {
        this.mEmptyWidth = width;
        this.mEmptyHeight = height;
        return this;
    }

    /**
     * 如果适配器数据为空并且要显示headview和footview，则设置isHeadAndEmpty true和isFootAndEmpty true
     *
     * @param isHeadAndEmpty
     * @param isFootAndEmpty
     */
    public UniversalAdapter<T, VH> setHeaderFooterEmpty(boolean isHeadAndEmpty, boolean isFootAndEmpty) {
        mHeadAndEmptyEnable = isHeadAndEmpty;
        mFootAndEmptyEnable = isFootAndEmpty;
        return this;
    }

    /**
     * 设置是否使用空视图
     *
     * @param isUseEmpty
     */
    public UniversalAdapter<T, VH> isUseEmpty(boolean isUseEmpty) {
        mIsUseEmpty = isUseEmpty;
        return this;
    }

    /**
     * 添加header（必须在recyclerView.setLayoutManager()后调用）
     *
     * @param view
     * @return header 的标识
     */
    public final UniversalAdapter<T, VH> addHeaderView(View view) {
        if (view == null) {
            return this;
        }
        if (mHeaderViews == null) {
            mHeaderViews = new SparseArray<>();
        }
        int itemType = getHeaderCount() + BASE_ITEM_TYPE_HEADER;
        mHeaderViews.put(itemType, view);
        return this;
    }

    /**
     * setAdapter之后添加header就调用这个方法
     *
     * @param view
     * @return header 的标识
     */
    public final UniversalAdapter<T, VH> addHeaderViewAfterSetAdapter(View view) {
        if (view == null) {
            return this;
        }
        int headerCount = getHeaderCount();
        addHeaderView(view);
        if (isEmpty) {
            if (mHeadAndEmptyEnable) {
                notifyItemInserted(headerCount);
            }
        } else {
            notifyItemInserted(headerCount);
        }
        return this;
    }

    /**
     * 添加footer（必须在recyclerView.setLayoutManager()后调用）
     *
     * @param view
     * @return footer 的标识
     */
    public final UniversalAdapter<T, VH> addFooterView(View view) {
        if (view == null) {
            return this;
        }
        if (mFooterViews == null) {
            mFooterViews = new SparseArray<>();
        }
        int itemType = getFooterCount() + BASE_ITEM_TYPE_FOOTER;
        mFooterViews.put(itemType, view);
        return this;
    }

    /**
     * setAdapter之后添加footer就调用这个方法
     *
     * @param view
     * @return footer 的标识
     */
    public final UniversalAdapter<T, VH> addFooterViewAfterSetAdapter(View view) {
        if (view == null) {
            return this;
        }
        addFooterView(view);
        if (isEmpty) {
            if (mFootAndEmptyEnable) {
                notifyItemInserted(getHeaderCount() + 1 + getFooterCount());
            }
        } else {
            notifyItemInserted(getHeaderCount() + getDataSize() + getFooterCount());
        }
        return this;
    }

    /**
     * 移除HeaderView
     *
     * @param position position
     */
    public final void removeHeaderView(int position) {
        int count = getHeaderCount();
        if (mHeaderViews != null && position >= 0 && count >= position) {
            mHeaderViews.removeAt(position);
            if (isEmpty) {
                if (mHeadAndEmptyEnable) {
                    notifyItemRemoved(position);
                }
            } else {
                notifyItemRemoved(position);
                int dataSize = getDataSize();
                if (dataSize > 0) {
                    notifyItemRangeChanged(--count, dataSize);
                }
            }
        }
    }

    /**
     * 移除header
     *
     * @param view
     */
    public final void removeHeaderView(View view) {
        if (mHeaderViews == null || view == null) {
            return;
        }
        int index = mHeaderViews.indexOfValue(view);
        if (index < 0) {
            return;
        }
        removeHeaderView(index);
    }

    /**
     * 删除所有header
     */
    public final void removeAllHeaders() {
        int count = getHeaderCount();
        if (count > 0) {
            mHeaderViews.clear();
            if (isEmpty) {
                if (mHeadAndEmptyEnable) {
                    notifyItemRangeRemoved(0, count);
                }
            } else {
                notifyItemRangeRemoved(0, count);
                int dataSize = getDataSize();
                if (dataSize > 0) {
                    notifyItemRangeChanged(0, dataSize);
                }
            }
        }
    }

    /**
     * 移除footer
     *
     * @param position position
     */
    public final void removeFooterView(int position) {
        int count = getFooterCount();
        if (mFooterViews != null && position >= 0 && count >= position) {
            mFooterViews.removeAt(position);
            if (isEmpty) {
                if (mFootAndEmptyEnable) {
                    notifyItemRemoved(getHeaderCount() + 1 + position);
                }
            } else {
                notifyItemRemoved(getHeaderCount() + getDataSize() + position);
            }
        }
    }

    /**
     * 移除footer
     *
     * @param view
     */
    public final void removeFooterView(View view) {
        if (mFooterViews == null || view == null) {
            return;
        }
        int index = mFooterViews.indexOfValue(view);
        if (index < 0) {
            return;
        }
        removeFooterView(index);
    }

    /**
     * 删除所有footer
     */
    public final void removeAllFooters() {
        int count = getFooterCount();
        if (count > 0) {
            mFooterViews.clear();
            if (isEmpty) {
                if (mFootAndEmptyEnable) {
                    notifyItemRangeRemoved(getHeaderCount() + 1, count);
                }
            } else {
                notifyItemRangeRemoved(getHeaderCount() + getDataSize(), count);
            }
        }
    }

    /**
     * 头部数量
     *
     * @return
     */
    public final int getHeaderCount() {
        if (mHeaderViews == null) {
            return 0;
        }
        return mHeaderViews.size();
    }

    /**
     * 底部数量
     *
     * @return
     */
    public final int getFooterCount() {
        if (mFooterViews == null) {
            return 0;
        }
        return mFooterViews.size();
    }

    /**
     * 获取上拉加载更多数量
     *
     * @return
     */
    private final int getLoadViewCount() {
        if (!mEnableLoadMore) {
            return 0;
        }
        if (getDataSize() <= 0) {
            return 0;
        }
        if (!AdapterLoadSir.getDefault().isCommit()) {
            return 0;
        }
        if (AdapterLoadSir.getDefault().getBuilder().getLoadCallbackSize() == 0) {
            return 0;
        }
        if (AdapterLoadSir.getDefault().getBuilder().getDefaultLoadCallback() == null && mLoadCallback == null) {
            return 0;
        }
        return 1;
    }

    /**
     * 空布局数量
     *
     * @return
     */
    public final int getEmptyViewCount() {
        if (!mIsUseEmpty) {
            return 0;
        }
        if (getDataSize() > 0) {
            return 0;
        }
        if (!AdapterLoadSir.getDefault().isCommit()) {
            return 0;
        }
        if (AdapterLoadSir.getDefault().getBuilder().getCallbackSize() == 0) {
            return 0;
        }
        if (AdapterLoadSir.getDefault().getBuilder().getDefaultCallback() == null && mCallback == null) {
            return 0;
        }
        return 1;
    }

    /**
     * 获取真实的数据条数
     *
     * @return
     */
    public final int getDataSize() {
        if (mData != null) {
            return mData.size();
        }
        return 0;
    }

    /**
     * 判断是不是Header
     *
     * @param viewType
     * @return
     */
    public final boolean isHeaderViewType(int viewType) {
        int size = getHeaderCount();
        if (size <= 0) {
            return false;
        }
        if (isEmpty) {
            if (mHeadAndEmptyEnable) {
                return viewType >= BASE_ITEM_TYPE_HEADER && viewType < BASE_ITEM_TYPE_HEADER + size;
            }
            return false;
        }
        return viewType >= BASE_ITEM_TYPE_HEADER && viewType < BASE_ITEM_TYPE_HEADER + size;
    }

    /**
     * 判断是不是Footer
     *
     * @param viewType
     * @return
     */
    public final boolean isFooterViewType(int viewType) {
        int size = getFooterCount();
        if (size <= 0) {
            return false;
        }
        if (isEmpty) {
            if (mFootAndEmptyEnable) {
                return viewType >= BASE_ITEM_TYPE_FOOTER && viewType < BASE_ITEM_TYPE_FOOTER + size;
            }
            return false;
        }
        return viewType >= BASE_ITEM_TYPE_FOOTER && viewType < BASE_ITEM_TYPE_FOOTER + size;
    }

    /**
     * 判断是不是Header
     *
     * @param position
     * @return
     */
    public final boolean isHeaderView(int position) {
        int size = getHeaderCount();
        if (size <= 0 || position >= size) {
            return false;
        }
        if (isEmpty) {
            return mHeadAndEmptyEnable;
        }
        return true;
    }

    /**
     * 判断是不是Footer
     *
     * @param position
     * @return
     */
    public final boolean isFooterView(int position) {
        int size = getFooterCount();
        if (size <= 0 || position < 0) {
            return false;
        }
        if (isEmpty) {
            if (mFootAndEmptyEnable) {
                int headerCount = getHeaderCount();
                return position >= headerCount + 1 && position < headerCount + 1 + size;
            }
        } else {
            int headerCount = getHeaderCount();
            int dataSize = getDataSize();
            return position >= headerCount + dataSize && position < headerCount + dataSize + size;
        }
        return false;
    }

    /**
     * 判断是不是空布局
     *
     * @param position
     * @return
     */
    public final boolean isEmptyLayout(int position) {
        if (!isEmpty) {
            return false;
        }
        if (!mHeadAndEmptyEnable) {
            return position == 0;
        }
        return position == getHeaderCount();
    }

    /**
     * 判断是不是空布局
     *
     * @return
     */
    protected final boolean isEmptyLayout() {
        if (!mIsUseEmpty) {
            return false;
        }
        if (getDataSize() > 0) {
            return false;
        }
        return true;
    }

    /**
     * 判断是不是加载更多
     *
     * @param position
     * @return
     */
    public final boolean isLoadView(int position) {
        return position == getHeaderCount() + getDataSize() + getFooterCount();
    }

    /**
     * 获取数据
     *
     * @return
     */
    public final List<T> getData() {
        return mData;
    }

    /**
     * 是否是第一个Item
     *
     * @param position
     * @return true 是，false 否
     */
    public final boolean isFirstItem(int position) {
        if (position >= 0 && getDataSize() > position) {
            return position == 0;
        }
        return false;
    }

    /**
     * 是否是最后一个Item
     *
     * @param position
     * @return true 是，false 否
     */
    public final boolean isLastItem(int position) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            return position == dataSize - 1;
        }
        return false;
    }

    /**
     * 获取单条数据
     *
     * @param position
     * @return
     */
    public final T getItem(int position) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            return mData.get(position);
        }
        return null;
    }

    /**
     * 设置新数据
     *
     * @param list
     */
    public final void setData(List<T> list) {
        if (mData != null) {
            mData.clear();
        }
        if (list == null || list.size() <= 0) {
            return;
        }
        if (mData == null) {
            mData = new ArrayList<>();
        }
        mData.addAll(list);
    }

    /**
     * 添加数据
     *
     * @param element
     */
    public final boolean addItem(T element) {
        if (mData != null) {
            return mData.add(element);
        }
        return false;
    }

    /**
     * 添加数据
     *
     * @param position
     * @param element
     */
    public final void addItem(int position, T element) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            mData.add(position, element);
        }
    }

    /**
     * 添加列表数据
     *
     * @param list
     */
    public final boolean addAllItem(List<T> list) {
        if (mData != null && list != null && list.size() > 0) {
            return mData.addAll(list);
        }
        return false;
    }

    /**
     * 添加列表数据
     *
     * @param list
     */
    public final boolean addAllItem(int position, List<T> list) {
        int dataSize = getDataSize();
        if (mData != null && position >= 0 && dataSize >= position && list != null && list.size() > 0) {
            return mData.addAll(position, list);
        }
        return false;
    }

    /**
     * 修改数据
     *
     * @param position
     * @param element
     */
    public final T setItem(int position, T element) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            return mData.set(position, element);
        }
        return null;
    }

    /**
     * 删除数据
     *
     * @param position
     */
    public final T removeItem(int position) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            return mData.remove(position);
        }
        return null;
    }

    /**
     * 删除数据
     *
     * @param element
     */
    public final T removeItem(T element) {
        if (mData != null) {
            int index = mData.indexOf(element);
            if (index != -1) {
                return mData.remove(index);
            }
        }
        return null;
    }

    /**
     * 获取数据的index
     *
     * @param element
     * @return
     */
    public final int indexOf(T element) {
        if (mData != null) {
            return mData.indexOf(element);
        }
        return -1;
    }

    /**
     * 移动数据
     *
     * @param fromPosition
     * @param toPosition
     */
    public final void moveItem(int fromPosition, int toPosition) {
        int dataSize = getDataSize();
        if (fromPosition != toPosition && fromPosition >= 0 && dataSize > fromPosition && toPosition >= 0 && dataSize > toPosition) {
            if (fromPosition < toPosition) {
                for (int i = fromPosition; i < toPosition; i++) {
                    Collections.swap(mData, i, i + 1);
                }
            } else {
                for (int i = fromPosition; i > toPosition; i--) {
                    Collections.swap(mData, i, i - 1);
                }
            }
        }
    }

    /**
     * 清除数据
     */
    public final void clearItems() {
        if (mData != null) {
            mData.clear();
        }
    }

    /**
     * 使用DiffResult设置新数据
     *
     * @param baseQuickDiffCallback implementation {@link BaseDiffCallback}
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean setNewDiffData(@NonNull BaseDiffCallback<T> baseQuickDiffCallback) {
        return setNewDiffData(baseQuickDiffCallback, false);
    }

    /**
     * 使用DiffResult设置新数据
     * <p>
     * 这是异步刷新的方法，如果需要使用异步刷新的方法，请参阅 {@link #setNewDiffData(DiffUtil.DiffResult, List)}.
     *
     * @param baseQuickDiffCallback implementation {@link BaseDiffCallback}
     * @param detectMoves           是否有移动的item
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean setNewDiffData(@NonNull BaseDiffCallback<T> baseQuickDiffCallback, boolean detectMoves) {
        List<T> newList = baseQuickDiffCallback.getNewList();
        if (newList == null || newList.size() <= 0 || isEmptyLayout()) {
            // 如果当前时空View或新数组是空数组，则直接设置新数据或删除旧数据。
            return setNewData(newList);
        }
        baseQuickDiffCallback.setOldList(getData());
        DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(baseQuickDiffCallback, detectMoves);
        diffResult.dispatchUpdatesTo(new AdapterListUpdateCallback(this));
        mData = newList;
        return false;
    }

    /**
     * 使用DiffResult设置新数据
     * <p>
     * 如果需要使用Diff异步计算，请使用此方法。
     * 只需告诉计算结果，此适配器不关心计算过程。
     *
     * @param diffResult DiffResult
     * @param newData    新数据
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean setNewDiffData(@NonNull DiffUtil.DiffResult diffResult, List<T> newData) {
        if (newData == null || newData.size() <= 0 || isEmptyLayout()) {
            // 如果当前时空View或新数组是空数组，则直接设置新数据或删除旧数据。
            return setNewData(newData);
        }
        diffResult.dispatchUpdatesTo(new AdapterListUpdateCallback(this));
        mData = newData;
        return false;
    }

    /**
     * 使用DiffResult设置新数据
     *
     * @param baseQuickDiffCallback implementation {@link BaseDiffCallback}
     * @param listUpdateCallback    implementation {@link ListUpdateCallback}
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean setNewDiffData(@NonNull BaseDiffCallback<T> baseQuickDiffCallback, @NonNull ListUpdateCallback listUpdateCallback) {
        return setNewDiffData(baseQuickDiffCallback, listUpdateCallback, false);
    }

    /**
     * 使用DiffResult设置新数据
     * <p>
     * 这是异步刷新的方法，如果需要使用异步刷新的方法，请参阅 {@link #setNewDiffData(DiffUtil.DiffResult, List)}.
     *
     * @param baseQuickDiffCallback implementation {@link BaseDiffCallback}
     * @param listUpdateCallback    implementation {@link ListUpdateCallback}
     * @param detectMoves           是否有移动的item
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean setNewDiffData(@NonNull BaseDiffCallback<T> baseQuickDiffCallback, @NonNull ListUpdateCallback listUpdateCallback, boolean detectMoves) {
        List<T> newList = baseQuickDiffCallback.getNewList();
        if (newList == null || newList.size() <= 0 || isEmptyLayout()) {
            // 如果当前时空View或新数组是空数组，则直接设置新数据或删除旧数据。
            return setNewData(newList);
        }
        baseQuickDiffCallback.setOldList(getData());
        DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(baseQuickDiffCallback, detectMoves);
        diffResult.dispatchUpdatesTo(listUpdateCallback);
        mData = newList;
        return false;
    }

    /**
     * 使用DiffResult设置新数据
     * <p>
     * 如果需要使用Diff异步计算，请使用此方法。
     * 只需告诉计算结果，此适配器不关心计算过程。
     *
     * @param diffResult         DiffResult
     * @param listUpdateCallback implementation {@link ListUpdateCallback}
     * @param newData            新数据
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean setNewDiffData(@NonNull DiffUtil.DiffResult diffResult, @NonNull ListUpdateCallback listUpdateCallback, List<T> newData) {
        if (newData == null || newData.size() <= 0 || isEmptyLayout()) {
            // 如果当前时空View或新数组是空数组，则直接设置新数据或删除旧数据。
            return setNewData(newData);
        }
        diffResult.dispatchUpdatesTo(listUpdateCallback);
        mData = newData;
        return false;
    }

    /**
     * 新数据设置并更新
     *
     * @param list
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean setNewData(List<T> list) {
        int dataSize = getDataSize();
        if (list == null || list.size() <= 0) {
            if (dataSize > 0) {
                mData.clear();
                if (isEmptyLayout()) {
                    notifyDataSetChanged();
                    return true;
                } else {
                    notifyItemRangeRemoved(getHeaderCount(), dataSize);
                }
            }
            return isEmptyLayout();
        }
        boolean isEmpty = isEmptyLayout();
        int size = list.size();
        if (mData == null) {
            mData = new ArrayList<>();
        }
        if (dataSize > 0) {
            mData.clear();
        }
        if (!mData.addAll(list)) {
            if (isEmpty) {
                notifyDataSetChanged();
                return true;
            } else {
                notifyItemRangeRemoved(getHeaderCount(), dataSize);
                return false;
            }
        }
        if (dataSize > 0) {
            int headerCount = getHeaderCount();
            if (dataSize > size) {
                notifyItemRangeChanged(headerCount, size);
                notifyItemRangeRemoved(headerCount + size, dataSize - size);
            } else if (dataSize < size) {
                notifyItemRangeChanged(headerCount, dataSize);
                notifyItemRangeInserted(headerCount + dataSize, size - dataSize);
            } else {
                notifyItemRangeChanged(headerCount, size);
            }
        } else {
            if (isEmpty) {
                notifyDataSetChanged();
            } else {
                notifyItemRangeInserted(getHeaderCount(), size);
            }
        }
        return false;
    }

    /**
     * 添加数据并更新
     *
     * @param element
     * @return true 添加成功，false 添加失败
     */
    public final boolean notifyItemInsert(T element) {
        if (mData != null) {
            int dataSize = getDataSize();
            boolean isEmpty = isEmptyLayout();
            if (mData.add(element)) {
                if (isEmpty) {
                    notifyDataSetChanged();
                } else {
                    notifyItemInserted(getHeaderCount() + dataSize);
                }
                return true;
            }
        }
        return false;
    }

    /**
     * 添加数据并更新
     *
     * @param position
     * @param element
     * @return true 添加成功，false 添加失败
     */
    public final boolean notifyItemInsert(int position, T element) {
        int dataSize = getDataSize();
        if (mData != null && position >= 0 && dataSize >= position) {
            boolean isEmpty = isEmptyLayout();
            mData.add(position, element);
            if (isEmpty) {
                notifyDataSetChanged();
            } else {
                int headerCount = getHeaderCount();
                notifyItemInserted(position + headerCount);
                notifyItemRangeChanged(headerCount + position + 1, dataSize - position);
            }
            return true;
        }
        return false;
    }

    /**
     * 添加列表数据并更新
     *
     * @param list
     * @return true 添加成功，false 添加失败
     */
    public final boolean notifyItemInsert(List<T> list) {
        if (mData != null && list != null && list.size() > 0) {
            int size = list.size();
            int dataSize = getDataSize();
            boolean isEmpty = isEmptyLayout();
            if (mData.addAll(list)) {
                if (isEmpty) {
                    notifyDataSetChanged();
                } else {
                    notifyItemRangeInserted(getHeaderCount() + dataSize, size);
                }
                return true;
            }
        }
        return false;
    }

    /**
     * 添加列表数据并更新
     *
     * @param position
     * @param list
     * @return true 添加成功，false 添加失败
     */
    public final boolean notifyItemInsert(int position, List<T> list) {
        if (mData != null && list != null && list.size() > 0) {
            int size = list.size();
            int dataSize = getDataSize();
            boolean isEmpty = isEmptyLayout();
            if (mData.addAll(position, list)) {
                if (isEmpty) {
                    notifyDataSetChanged();
                } else {
                    int headerCount = getHeaderCount();
                    notifyItemRangeInserted(headerCount + position, size);
                    notifyItemRangeChanged(headerCount + position + size, dataSize - position);
                }
                return true;
            }
        }
        return false;
    }

    /**
     * 修改数据并更新
     *
     * @param position
     * @param element
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyDataChange(int position, T element) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            mData.set(position, element);
            notifyItemChanged(position + getHeaderCount());
            return true;
        }
        return false;
    }

    /**
     * 修改数据并更新
     *
     * @param position
     * @param element
     * @param payload
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyItemChange(int position, T element, Object payload) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            mData.set(position, element);
            notifyItemChanged(position + getHeaderCount(), payload);
            return true;
        }
        return false;
    }

    /**
     * 删除数据并更新
     *
     * @param position
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean notifyItemRemove(int position) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            mData.remove(position);
            dataSize--;
            if (dataSize > 0) {
                int start = getHeaderCount() + position;
                notifyItemRemoved(start);
                if (isLastItem(position - 1)) {
                    notifyLastRowChanged(dataSize);
                } else {
                    notifyItemRangeChanged(start, dataSize - position);
                }
            } else {
                if (isEmptyLayout()) {
                    notifyDataSetChanged();
                    return true;
                } else {
                    notifyItemRemoved(getHeaderCount());
                }
            }
            return false;
        }
        return isEmptyLayout();
    }

    /**
     * 删除数据并更新
     *
     * @param element
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean notifyItemRemove(T element) {
        if (mData != null) {
            int index = mData.indexOf(element);
            if (index != -1) {
                return notifyItemRemove(index);
            }
            return false;
        }
        return isEmptyLayout();
    }

    /**
     * 删除某个位置后面特定条数数据并更新
     *
     * @param positionStart 开始删除的 position (包含)
     * @param itemCount     删除的条数
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean notifyItemRangeRemove(int positionStart, int itemCount) {
        int dataSize = getDataSize();
        if (positionStart >= 0 && dataSize > positionStart && itemCount > 0) {
            int headerCount = getHeaderCount();
            int removePosition = headerCount + positionStart;
            int maxItemCount = dataSize - positionStart;
            if (itemCount > maxItemCount) {
                itemCount = maxItemCount;
            }
            if (positionStart == 0 && maxItemCount == itemCount) {
                mData.clear();
                dataSize = 0;
            } else {
                for (int i = 0; i < itemCount; i++) {
                    mData.remove(positionStart);
                    dataSize--;
                }
            }
            boolean emptyLayout = isEmptyLayout();
            if (!emptyLayout) {
                notifyItemRangeRemoved(getHeaderCount() + positionStart, itemCount);
                if (dataSize > 0) {
                    if (isLastItem(positionStart - 1)) {
                        notifyLastRowChanged(dataSize);
                    } else {
                        notifyItemRangeChanged(removePosition, dataSize - positionStart);
                    }
                }
            } else {
                notifyDataSetChanged();
            }
            return emptyLayout;
        }
        return isEmptyLayout();
    }

    /**
     * 删除某个位置后面所有的数据并更新
     *
     * @param positionStart 开始删除的 position (包含)
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean notifyItemRangeRemove(int positionStart) {
        int dataSize = getDataSize();
        if (positionStart >= 0 && dataSize > positionStart) {
            int itemCount = dataSize - positionStart;
            if (positionStart == 0) {
                mData.clear();
                dataSize = 0;
            } else {
                for (int i = 0; i < itemCount; i++) {
                    mData.remove(positionStart);
                    dataSize--;
                }
            }
            boolean emptyLayout = isEmptyLayout();
            if (!emptyLayout) {
                notifyItemRangeRemoved(getHeaderCount() + positionStart, itemCount);
                if (dataSize > 0) {
                    notifyLastRowChanged(dataSize);
                }
            } else {
                notifyDataSetChanged();
            }
            return emptyLayout;
        }
        return isEmptyLayout();
    }

    /**
     * 移动数据并更新
     *
     * @param fromPosition item 上一个位置
     * @param toPosition   item 新位置
     * @return true 移动成功，false 移动失败
     */
    public final boolean notifyItemMove(int fromPosition, int toPosition) {
        int dataSize = getDataSize();
        if (fromPosition != toPosition && fromPosition >= 0 && dataSize > fromPosition && toPosition >= 0 && dataSize > toPosition) {
            if (fromPosition < toPosition) {
                for (int i = fromPosition; i < toPosition; i++) {
                    Collections.swap(mData, i, i + 1);
                }
            } else {
                for (int i = fromPosition; i > toPosition; i--) {
                    Collections.swap(mData, i, i - 1);
                }
            }
            int headerCount = getHeaderCount();
            fromPosition += headerCount;
            toPosition += headerCount;
            notifyItemMoved(fromPosition, toPosition);
            // 解决数据错乱问题
            notifyItemRangeChanged(Math.min(fromPosition, toPosition), Math.abs(fromPosition - toPosition) + 1);
            return true;
        }
        return false;
    }

    /**
     * 清除数据并更新
     *
     * @return true 需要显示空视图，false 不需要
     */
    public final boolean notifyItemClear() {
        int dataSize = getDataSize();
        if (dataSize > 0) {
            mData.clear();
            if (isEmptyLayout()) {
                notifyDataSetChanged();
                return true;
            } else {
                notifyItemRangeRemoved(getHeaderCount(), dataSize);
                return false;
            }
        }
        return isEmptyLayout();
    }

    /**
     * 更新item
     *
     * @param position item 更新的位置
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyItemChange(int position) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            notifyItemChanged(position + getHeaderCount());
            return true;
        }
        return false;
    }

    /**
     * 更新item
     *
     * @param position item 更新的位置
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyItemChange(int position, Object payload) {
        int dataSize = getDataSize();
        if (position >= 0 && dataSize > position) {
            notifyItemChanged(position + getHeaderCount(), payload);
            return true;
        }
        return false;
    }

    /**
     * 更新某个位置后面特定条数的item
     *
     * @param positionStart 开始更新的 position (包含)
     * @param itemCount     更新的条数
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyItemRangeChange(int positionStart, int itemCount) {
        int dataSize = getDataSize();
        if (positionStart >= 0 && dataSize > positionStart && itemCount > 0) {
            int maxItemCount = dataSize - positionStart;
            if (itemCount > maxItemCount) {
                itemCount = maxItemCount;
            }
            notifyItemRangeChanged(positionStart + getHeaderCount(), itemCount);
            return true;
        }
        return false;
    }

    /**
     * 更新某个位置后面特定条数的item
     *
     * @param positionStart 开始更新的 position (包含)
     * @param itemCount     更新的条数
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyItemRangeChange(int positionStart, int itemCount, Object payload) {
        int dataSize = getDataSize();
        if (positionStart >= 0 && dataSize > positionStart && itemCount > 0) {
            int maxItemCount = dataSize - positionStart;
            if (itemCount > maxItemCount) {
                itemCount = maxItemCount;
            }
            notifyItemRangeChanged(positionStart + getHeaderCount(), itemCount, payload);
            return true;
        }
        return false;
    }

    /**
     * 更新某个位置后面所有的item
     *
     * @param positionStart 开始更新的 position (包含)
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyItemRangeChange(int positionStart) {
        int dataSize = getDataSize();
        if (positionStart >= 0 && dataSize > positionStart) {
            notifyItemRangeChanged(positionStart + getHeaderCount(), dataSize - positionStart);
            return true;
        }
        return false;
    }

    /**
     * 更新某个位置后面所有的item
     *
     * @param positionStart 开始更新的 position (包含)
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyItemRangeChange(int positionStart, Object payload) {
        int dataSize = getDataSize();
        if (positionStart >= 0 && dataSize > positionStart) {
            notifyItemRangeChanged(positionStart + getHeaderCount(), dataSize - positionStart, payload);
            return true;
        }
        return false;
    }

    /**
     * 移动数据并更新
     *
     * @param fromPosition item 上一个位置
     * @param toPosition   item 新位置
     * @return true 移动成功，false 移动失败
     */
    public final boolean notifyItemRangeMoved(int fromPosition, int toPosition) {
        int dataSize = getDataSize();
        if (fromPosition != toPosition && fromPosition >= 0 && dataSize > fromPosition && toPosition >= 0 && dataSize > toPosition) {
            int headerCount = getHeaderCount();
            fromPosition += headerCount;
            toPosition += headerCount;
            notifyItemMoved(fromPosition, toPosition);
            // 解决数据错乱问题
            notifyItemRangeChanged(Math.min(fromPosition, toPosition), Math.abs(fromPosition - toPosition) + 1);
            return true;
        }
        return false;
    }

    /**
     * 更新所有数据
     *
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyDataSetChange(Object payload) {
        int dataSize = getDataSize();
        if (dataSize > 0) {
            notifyItemRangeChanged(getHeaderCount(), dataSize, payload);
            return true;
        }
        return false;
    }

    /**
     * 更新所有数据
     *
     * @return true 修改成功，false 修改失败
     */
    public final boolean notifyDataSetChange() {
        return notifyDataSetChange(null);
    }
}
